using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using WebApplication8.Data;

namespace WebApplication8.Areas.Identity.Pages.Account.Manage
{
  public partial class IndexModel : PageModel
  {
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly IEmailSender _emailSender;

    public IndexModel(
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        IEmailSender emailSender)
    {
      _userManager = userManager;
      _signInManager = signInManager;
      _emailSender = emailSender;
    }

    [DisplayName("用户名")]
    public string Username { get; set; }

    public bool IsEmailConfirmed { get; set; }

    [TempData]
    public string StatusMessage { get; set; }

    [BindProperty]
    public InputModel Input { get; set; }

    public class InputModel
    {
      [DisplayName("姓名")]
      public string NickName { get; set; }


      [EmailAddress]
      public string Email { get; set; }

      [Phone]
      [Display(Name = "手机号")]
      public string PhoneNumber { get; set; }
    }

    public async Task<IActionResult> OnGetAsync()
    {
      var user = await _userManager.GetUserAsync(User);
      if (user == null)
      {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
      }

      var userName = await _userManager.GetUserNameAsync(user);
      var email = await _userManager.GetEmailAsync(user);

      var phoneNumber = await _userManager.GetPhoneNumberAsync(user);

      Username = userName;

      Input = new InputModel
      {
        NickName = user.NickName,
        Email = email,
        PhoneNumber = phoneNumber
      };

      IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);

      return Page();
    }

    public async Task<IActionResult> OnPostAsync()
    {
      if (!ModelState.IsValid)
      {
        return Page();
      }

      var user = await _userManager.GetUserAsync(User);
      if (user == null)
      {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
      }

      var email = await _userManager.GetEmailAsync(user);
      if (Input.Email != email)
      {
        var setEmailResult = await _userManager.SetEmailAsync(user, Input.Email);
        if (!setEmailResult.Succeeded)
        {
          var userId = await _userManager.GetUserIdAsync(user);
          throw new InvalidOperationException($"Unexpected error occurred setting email for user with ID '{userId}'.");
        }
      }


      var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
      if (Input.PhoneNumber != phoneNumber)
      {
        var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
        if (!setPhoneResult.Succeeded)
        {
          var userId = await _userManager.GetUserIdAsync(user);
          throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{userId}'.");
        }
      }
      if (Input.NickName != user.NickName)
      {
        if (!string.IsNullOrWhiteSpace(Input.NickName))
        {
          user.NickName = Input.NickName;
          await _userManager.UpdateAsync(user);
        }
      }

      await _signInManager.RefreshSignInAsync(user);
      StatusMessage = "Your profile has been updated";
      return RedirectToPage();
    }

    public async Task<IActionResult> OnPostSendVerificationEmailAsync()
    {
      if (!ModelState.IsValid)
      {
        return Page();
      }

      var user = await _userManager.GetUserAsync(User);
      if (user == null)
      {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
      }


      var userId = await _userManager.GetUserIdAsync(user);
      var email = await _userManager.GetEmailAsync(user);
      var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
      var callbackUrl = Url.Page(
          "/Account/ConfirmEmail",
          pageHandler: null,
          values: new { userId = userId, code = code },
          protocol: Request.Scheme);
      await _emailSender.SendEmailAsync(
          email,
          "Confirm your email",
          $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

      StatusMessage = "Verification email sent. Please check your email.";
      return RedirectToPage();
    }
  }
}
